﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using M3G;

/**
 * FindとDuplicateのテストは未実装
 * それらは仮想関数を使って実装され派生先のテストクラスでテストする
 */
/*
 * Animateのテストも未実装
 * どうやってテストするかな-
 */

namespace MyTestProject {

    public class TestObject3D {


        [Fact]
        public void TestConstructor () {
            var obj = new Group ();

            Assert.Equal (0, obj.UserID);
            Assert.Equal (null, obj.UserObject);
            Assert.Equal (0, obj.AnimationTrackCount);
            Assert.Equal (true, obj.AnimationEnabled);
        }

        int a;

        void handler (object sender, EventArgs e) {
            a = 1;    
        }

        [Fact]
        public void TestDisposeEvent () {
            var obj = new Group ();

            obj.DisposeEvent += new DisposeEventHandler(handler);
            obj.DisposeEvent -= new DisposeEventHandler (handler);
            obj.Dispose ();

            Assert.Equal (1, a);
        }

        [Fact]
        public void TestSetUserID () {
            var obj = new Group ();
            obj.UserID = 100;

            Assert.Equal (100, obj.UserID);
        }

        [Fact]
        public void TestSetUserObject () {
            var obj = new Group ();
            var uo = "Eila Ilmatar Juutilainen";
            obj.UserObject = uo;

            Assert.Equal (uo, obj.UserObject);
        }

        [Fact]
        public void TestFind1 () {
            Object3D obj = new Group ();
            obj.UserID = 100;

            Assert.Equal (obj, obj.Find (100));
            Assert.Equal (null, obj.Find (101));
        }

        /*
         * Find()の仮想関数のチェーンが回っていることを確認するテスト
         * */
        [Fact]
        public void TestFind2 () {
            var node   = new Group ();
            var keyseq = new KeyframeSequence (4, 3, KeyframeSequence.Step);
            var track  = new AnimationTrack (keyseq, AnimationTrack.Color);
            var ctrl   = new AnimationController ();
            track.SetController (ctrl);
            node.AddAnimationTrack (track);

            node.UserID = 100;
            keyseq.UserID = 101;
            track.UserID = 102;
            ctrl.UserID = 103;

            Assert.Equal (node, node.Find (100));
            Assert.Equal (keyseq, node.Find (101));
            Assert.Equal (track, node.Find (102));
            Assert.Equal (ctrl, node.Find (103));
        }

        [Fact]
        public void TestFindAll () {
            Object3D obj = new Group ();

            var expected1 = new Object3D[] { obj };
            var expected2 = new Group[] { (Group)obj };

            Assert.Equal (expected1, obj.FindAll<Object3D> ());
            Assert.Equal (expected2, obj.FindAll<Group> ());
        }


        [Fact]
        public void TestSetAnimationEnabled () {
            var obj = new Group ();
            obj.AnimationEnabled = false;

            Assert.Equal (false, obj.AnimationEnabled);
        }

        [Fact]
        public void TestAddAnimationTrack () {
            var obj = new Group ();
            var kseq = new KeyframeSequence (4, 4, 3, KeyframeSequence.Linear);
            var anim1 = new AnimationTrack (kseq, AnimationTrack.Color);
            var anim2 = new AnimationTrack (kseq, AnimationTrack.Color);
            obj.AddAnimationTrack (anim1);     // channel 0
            obj.AddAnimationTrack (anim2, 3);  // channel 3

            Assert.Equal (2, obj.AnimationTrackCount);
            Assert.Equal (anim1, obj.AnimationTrack[0]);
            Assert.Equal (anim2, obj.AnimationTrack[1]);
            Assert.Equal (0, obj.AnimationTrackChannel[0]);
            Assert.Equal (3, obj.AnimationTrackChannel[1]);
        }

        [Fact]
        public void TestRemoveAnimationTrack () {
            var obj = new Group ();
            var kseq = new KeyframeSequence (4, 4, 3, KeyframeSequence.Linear);
            var anim = new AnimationTrack (kseq, AnimationTrack.Color);
            obj.AddAnimationTrack (anim);     // channel 0
            obj.AddAnimationTrack (anim, 3);  // channel 3

            Assert.Equal (2, obj.AnimationTrackCount);

            obj.RemoveAnimationTrack (anim);

            Assert.Equal (0, obj.AnimationTrackCount);
        }

        [Fact]
        public void TestFindAnimationEvents () {
            var obj = new Group ();
            var kseq = new KeyframeSequence (4, 4, 3, KeyframeSequence.Linear);
            var anim1 = new AnimationTrack (kseq, AnimationTrack.Color);
            var anim2 = new AnimationTrack (kseq, AnimationTrack.Color);
            obj.AddAnimationTrack (anim1);     // channel 0
            obj.AddAnimationTrack (anim2, 3);  // channel 3

        }

        [Fact]
        public void TestReferences () {
            var keyseq = new KeyframeSequence (4, 3, KeyframeSequence.Linear);
            var track = new AnimationTrack (keyseq, AnimationTrack.DiffuseColor);

            var obj = new Group ();
            obj.AddAnimationTrack (track);

            var refs = obj.References;

            Assert.Equal (1, refs.Length);
            Assert.Equal (track, refs[0]);
        }

        [Fact]
        public void TestGetReferences () {
            var obj = new Group ();

            var outRefs      = new Object3D[0];
            var expectedRefs = new Object3D[] { };

            Assert.Equal (0, obj.GetReferences (null));
            Assert.Equal (0, obj.GetReferences (outRefs));
        }

    }
}
